#pragma once
#include <map>
#include <string>
#include <list>

#include "../expr/MySqlExprImpl.h"
#include "../../../../ast/statement/SQLCreateTableStatement.h"
#include "MySqlStatement.h"
#include "../../../../../utils/common_ptr.h"

class SQLName;
class SQLExpr;
class SQLObject;
class SQLSelect;
class SQLCommentHint;
class SQLASTVisitor;
class AdsOutputVisitor;
// class Appendable;
class MySqlKey;
class MySqlTableIndex;
class SQLAlterTableItem;
class SQLAlterTableAddIndex;
class MySqlAlterTableOption;
class SQLAlterCharacter;
class MySqlAlterTableAlterColumn;
class MySqlAlterTableChangeColumn;
class MySqlAlterTableModifyColumn;
class MySqlExtPartition;
class MySqlRenameTableStatement;
class MySqlRenameTableStatement_Item;

class MySqlCreateTableStatement_TableSpaceOption
    : public MySqlExprImpl
{
public:
  SQLName_ptr name;
  SQLExpr_ptr storage;

  SHAREDOBJECT(MySqlCreateTableStatement_TableSpaceOption);
  SQLName_ptr getName();

  void setName(SQLName_ptr name);

  SQLExpr_ptr getStorage();

  void setStorage(SQLExpr_ptr storage);

  void accept0(MySqlASTVisitor_ptr visitor);

  // MySqlCreateTableStatement_TableSpaceOption *clone();
  virtual SQLObject_ptr clone();
  SQLObject_list_ptr getChildren();
};

class MySqlCreateTableStatement
    : public SQLCreateTableStatement,
      virtual public MySqlStatement
{
public:
  SQLCommentHint_list_ptr hints;
  SQLCommentHint_list_ptr optionHints;
  SQLName_ptr tableGroup;
  // for drds
  SQLExpr_ptr dbPartitionBy;
  // for drds
  SQLExpr_ptr dbPartitions;
  // for drds
  SQLExpr_ptr tablePartitionBy;
  // for drds
  SQLExpr_ptr tablePartitions;
  // for drds
  MySqlExtPartition_ptr exPartition;
  // for ads
  SQLName_ptr storedBy;
  // for ads
  SQLName_ptr distributeByType;
  SQLName_list_ptr distributeBy;
  BOOL_ptr isBroadCast_;
  // for ads
  std::shared_ptr<std::map<string_ptr, SQLName_ptr>> with;

  // adb
  SQLName_ptr archiveBy;
  BOOL_ptr withData;

  MySqlCreateTableStatement();
  SHAREDOBJECT(MySqlCreateTableStatement);

  SQLCommentHint_list_ptr getHints();

  void setHints(SQLCommentHint_list_ptr hints);

  SQLSelect_ptr getQuery();

  void setQuery(SQLSelect_ptr query);

  void accept0(SQLASTVisitor_ptr visitor);

  void accept0(AdsOutputVisitor_ptr visitor);

  void accept0(MySqlASTVisitor_ptr visitor);

  SQLCommentHint_list_ptr getOptionHints();

  void setOptionHints(SQLCommentHint_list_ptr optionHints);

  SQLName_ptr getTableGroup();

  void setTableGroup(SQLName_ptr tableGroup);

  void setTableGroup(string_ptr tableGroup);

  void simplify();

  void showCoumns(std::stringstream *out);

  std::shared_ptr<std::list<MySqlKey_ptr>> getMysqlKeys();

  std::shared_ptr<std::list<MySqlTableIndex_ptr>> getMysqlIndexes();

  BOOL_ptr apply(MySqlRenameTableStatement *x);

  BOOL_ptr alterApply(SQLAlterTableItem *item);

  BOOL_ptr apply(SQLAlterTableAddIndex *item);

  BOOL_ptr apply(MySqlAlterTableOption *item);

  BOOL_ptr apply(SQLAlterCharacter *item);

  BOOL_ptr apply(MySqlRenameTableStatement_Item *item);

  BOOL_ptr apply(MySqlAlterTableAlterColumn *x);

  BOOL_ptr apply(MySqlAlterTableChangeColumn *item);

  BOOL_ptr apply(MySqlAlterTableModifyColumn *item);

  void cloneTo(MySqlCreateTableStatement_ptr x);

  // MySqlCreateTableStatement *clone();
  virtual SQLObject_ptr clone();
  SQLExpr_ptr getDbPartitionBy();

  void setDbPartitionBy(SQLExpr_ptr x);

  SQLExpr_ptr getTablePartitionBy();

  void setTablePartitionBy(SQLExpr_ptr x);

  SQLName_ptr getDistributeByType();

  void setDistributeByType(SQLName_ptr distributeByType);

  SQLName_list_ptr getDistributeBy();

  SQLExpr_ptr getTbpartitions();

  SQLExpr_ptr getTablePartitions();

  void setTablePartitions(SQLExpr_ptr x);

  SQLExpr_ptr getDbpartitions();

  void setDbPartitions(SQLExpr_ptr x);

  MySqlExtPartition_ptr getExtPartition();

  void setExPartition(MySqlExtPartition_ptr x);

  SQLExpr_ptr getDbPartitions();

  SQLName_ptr getStoredBy();

  void setStoredBy(SQLName_ptr storedBy);

  std::shared_ptr<std::map<string_ptr, SQLName_ptr>> getWith();

  BOOL_ptr isBroadCast();

  void setBroadCast(BOOL_ptr broadCast);

  SQLName_ptr getArchiveBy();

  void setArchiveBy(SQLName_ptr archiveBy);

  BOOL_ptr getWithData();

  void setWithData(BOOL_ptr withData);

  SQLExpr_ptr getEngine();

  void setEngine(SQLExpr_ptr x);

  void setPageChecksum(SQLExpr_ptr x);

  void setTransactional(SQLExpr_ptr x);
};
